﻿#pragma once
#include "XyNet/Endpoint/RpcEndpoint.h"
#include "XyNet/Protocol/cpp/Rpc.service.h"

namespace XyNet
{
	class ServerBaseServiceImpl;
	class RpcSocketChannelManager;

	/// rpc服务端
	class XYNET_API RpcServer : public RpcEndpoint
	{
	public:
		/// rpc服务端配置
		class XYNET_API Config : public RpcEndpoint::Config
		{
		public:
			explicit Config(const string& baseFileName = "");

			/// 监听端口
			XYNET_CONFIG_CHECK_PROPERTY(Port, int, 12345, value >= 0 && value <= 65535);
			/// 最大连接数
			XYNET_CONFIG_CHECK_PROPERTY(MaxConnection, int, 10000, value > 0);
			/// 检查心跳时间间隔（秒）
			XYNET_CONFIG_CHECK_PROPERTY(CheckHeartBeatInterval, int, 60, value > 0);
		};

		//////////////////////////////////////////////////////////////////////////

	public:
		explicit RpcServer(shared_ptr<Config> config);
		~RpcServer();

		/// 获取配置
		shared_ptr<const Config> getConfig() const;

		/// 创建广播通道
		virtual shared_ptr<RpcBroadcastChannel> createBroadcastChannel() override;
		/// 查找套接字通道
		virtual shared_ptr<RpcSocketChannel> findSocketChannel(const Id& id) const override;
		/// 处理套接字通道异常
		virtual void handleSocketChannelException(
			shared_ptr<RpcSocketChannel> socketChannel, int errorCode) override;

	private:
		/// 开始接收连接
		void startAccept();
		/// 处理接收连接
		void handleAccept(shared_ptr<boost::asio::ip::tcp::socket> socket,
			const boost::system::error_code& error);

	private:
		/// boost.asio终端
		unique_ptr<boost::asio::ip::tcp::endpoint> _asioEndpoint;
		/// 连接接受器
		unique_ptr<boost::asio::ip::tcp::acceptor> _acceptor;

		/// 套接字通道管理器
		shared_ptr<RpcSocketChannelManager> _socketChannelManager;

		/// 基础服务
		ServerBaseServiceImpl* _baseService;
	};

	//////////////////////////////////////////////////////////////////////////

	class XYNET_API ServerBaseServiceImpl : public BaseService
	{
	private:
		/// 心跳检测器
		class XYNET_API HeartBeatChecker : public enable_shared_from_this<HeartBeatChecker>
		{
		public:
			HeartBeatChecker(ServerBaseServiceImpl* baseService,
				shared_ptr<RpcSocketChannel> socketChannel);

			void startTimer();
			void sendHeartBeat();

		private:
			static void handleCheckHeartBeat(
				weak_ptr<HeartBeatChecker> weakChecker, const boost::system::error_code& error);
			static void stopCheckerAndDisconnect(
				weak_ptr<HeartBeatChecker> weakChecker, int errorCode);

		private:
			/// 所属服务
			ServerBaseServiceImpl* _baseService;
			/// 检测的套接字通道
			const weak_ptr<RpcSocketChannel> _weakSocketChannel;
			/// 套接字通道Id
			const Id _socketChannelId;
			/// 检测的时间间隔
			const boost::posix_time::time_duration _checkInterval;
			/// 超时控制定时器
			boost::asio::deadline_timer _timer;
			/// 是否有心跳
			atomic<bool> _hasHeartBeat;
		};

		//////////////////////////////////////////////////////////////////////////

	public:
		ServerBaseServiceImpl(RpcServer* server);
		~ServerBaseServiceImpl();

		virtual void onSendError(SendErrorMethod::Argument* argument) override;

		virtual void onSendHeartBeat(SendHeartBeatMethod::Argument* argument) override;

		virtual void onGetUtcTime(GetUtcTimeMethod::Argument* argument) override;

		virtual void onGetBrokerQueries(GetBrokerQueriesMethod::Argument* argument) override;

		void addHeartBeatChecker(shared_ptr<RpcSocketChannel> socketChannel);
		void removeHeartBeatChecker(const Id& socketChannelId);

	private:
		RpcServer* _server;
		/// 检测的时间间隔
		const boost::posix_time::time_duration _checkInterval;
		SharedObject<map<Id, shared_ptr<HeartBeatChecker>>> _idHeartBeatCheckerMapObject;
	};
}